<?php

define('HTML_EOL', '<br>');

include "Request.php";
$request = new Request();
# echo $request->getArgument('view');
# exit;

class Calendar
{
    public $months_total = 12;
    private $years_total = 2020;
    protected $days_total = array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
    protected $day_total = 0;
    public $query_arg = array(
        'view' => null,
        'view_array' => null,
    );
    public $year_start = 2019;

    function __construct(Request $request)
    {
        $this->query_arg['view'] = $request->getArgument('view');

        $view = $this->query_arg['view'];
        $this->query_arg['view_array'] = explode('-', $view);
    }

    function __destruct()
    {

    }

    /*--

    --*/

    function years()
    {
        $result = array();
        $years_total = $this->years_total;
        $days_no = 0;
        $days_no_html = '';
        $days_total = 0;
        $days_array = array();
        $view = $this->query_arg['view'];
        $view_array = explode('-', $view);
        for ($i = $this->year_start; $i < $years_total; $i++) {
            $leap = $i % 4;
            $months = !in_array('m', $view_array) ? [$i] : self::months();
            # $days = self::days($leap);
            $days_in_year = !in_array('d', $view_array) ? [$i] : self::daysInYear($i);
            $days_in_months = !in_array('days', $view_array) ? [$days_in_year] : self::daysInMonths($days_in_year);
            # print_r($days_in_months);exit;
            # $this->days_total[1] = $leap ? 28 : 29;
            # $this->day_total += $days;
            $result[] = array($i, $leap, $months, $days_in_year, $this->day_total, $days_in_months);
            /*
            $days_number = (0 === $leap) ? 366 : 365;
            $days_total = self::numberToArray($days_number);
            $days_html = self::viewArrayToHTML($days_total);

            $days_no++;
            $days_total = $days_number * $days_no;
            $days_array[] = $days_total;
            */

            /*
            $day_total = self::numberToArray($days_total);
            $day_html = self::viewArrayToHTML($day_total);
            $days_no_html .= $day_html;
            */
        }
        # echo $days_html = self::viewArrayToHTML($days_array);exit;
        # print_r($days_array);exit;
        # echo $days_no_html;exit;
        return $result;
    }

    function months()
    {
        $result = array();
        $months_length = 1 + $this->months_total;
        for ($i = 1; $i < $months_length; $i++) {
            $result[] = $i;
        }
        return $result;
    }

    function days($leap)
    {
        $result = 0;
        $month_days = $this->days_total;
        $month_days[1] = $leap ? 28 : 29;
        foreach ($month_days as $days) {
            $result += $days;
        }
        return $result;
    }

    function daysInYear($year_nm = 1)
    {
        $result = array();
        $big_months = array(1, 3, 5, 7, 8, 10, 12);
        $small_months = array(4, 6, 9, 11);
        $year_months = array(2);
        $leap_year = $year_nm % 4;

        for ($i = 1; $i < 13; $i++) {
            $days = 31;
            if (in_array($i, $small_months)) {
                $days = 30;
            } elseif (in_array($i, $year_months)) {
                $days = 28;
                if (0 === $leap_year) {
                    $days = 29;
                }
            }
            $result[] = $days;
        }
        return $result;
    }

    function daysInMonths($days_in_year)
    {

        $result = array();
        foreach ($days_in_year as $months_days) {
            $result[] = $this->numberToArray($months_days);
        }
        # echo json_encode($result);
        return $days = $this->viewArrayToHTML($result);
        exit;
        return $result;
    }

    function numberToArray($month_days = 31, $first_day = 1, $define_value = null)
    {
        $result = array();
        # $month_days++;
        for ($i = $first_day; $i < $month_days; $i++) {
            if ($define_value) {
                $result[] = $define_value;
            } else {
                $result[] = $i;
            }
        }
        return $result;

    }

    function numberToArr($total_days = 31, $first_day = 1)
    {
        $result = array();
        for ($i = $first_day; $i < $total_days; $i++) {
            $result[] = $i;
        }
        return $result;
    }

    function getAll()
    {
        $result = array();
        $result['years'] = self::years();
        # $result['months'] = self::months();
        return $result;
    }

    function daysNo($years = array())
    {
        $day_no = 1;
        $view_array = $this->query_arg['view_array'];
        $result = array();
        $i = 0;
        foreach ($years as $year_row) {
            list($year, $leap, $months, $days, $day_total) = $year_row;
            $leap_no = $leap ? '1' : 0;
            $days_count = count($months);
            $year_days = 0 === $leap_no ? 367 : 366;

            if (!in_array('no', $view_array)) {
                $day_no += $days_count;
                $days_array = $this->numberToArray($day_no + 1, $day_no - $days_count + 1);
            } else {
                $day_no += $year_days;
                if (367 > $year_days) {
                    $days_array = $this->numberToArray($day_no, 1);
                } else {
                    $days_array = $this->numberToArr($day_no, $year_days);
                    # $days_array = $this->numberToArr(366, 733);
                    # print_r($days_array);exit;
                }
            }

            $result[] = array('day_no' => $day_no, 'days_array' => $days_array, 'year_days' => $year_days);
            $i++;
        }
        return $result;
    }

    function viewRows($years = [])
    {
        $html_tr = "";
        $day_no = 1;
        $leap = $year = $months = $days = $day_total = "";
        $view_array = $this->query_arg['view_array'];
        $leaps = array(0 => 'run', '1' => ' ');
        foreach ($years as $year_row) {
            # print_r($year_row);exit;
            list($year, $leap, $months, $days, $day_total, $days_in_months) = $year_row;
            $leap = $leap ? '1' : 0;
            $days_count = count($months);
            # print_r($days_count);exit;

            /* Data */
            $year_days = 0 === $leap ? 366 : 365;
            $seconds_array = $this->seconds(1, $year_days, 86400);

            if (!in_array('no', $view_array)) {
                $day_no += $days_count;
                $days_array = $this->numberToArray($day_no, $day_no - $days_count);
            } else {
                $day_no += $year_days;
                if (366 > $year_days) {
                    $days_array = $this->numberToArray($day_no, 1);
                } else {
                    $days_array = $this->numberToArr($day_no, $year_days);
                }
            }
            $years = $this->numberToArray($year_days, 0, $year);
            $years_no_array = $this->numberToArray($year_days, 0, $year);
            $leap_no_array = $this->numberToArray($year_days, 1, $leaps[$leap]);
            #print_r(array($days_no_array));exit;
            # ($years_array);exit;

            /* View */
            $years_html = !in_array('years', $view_array) ? $this->viewArrayToHTML($years) : $this->viewYearNoList($years_no_array, $years);
            # $year_html = preg_split('/<br>/', $years_html);
            # print_r([count($year_html)]);
            # exit;

            # $days_in_months_json = json_encode($days_in_months);
            $months = !in_array('months', $view_array) ? $this->viewArrayToHTML($months) : $this->viewMonthNoList($months, $days);
            $days = !in_array('days', $view_array) ? $this->viewArrayToHTML($days) : $this->viewMonthDays($days);

            $days_no = $this->viewArrayToHTML($days_array);
            $leap_html = $this->viewArrayToHTML($leap_no_array);
            $week_html = $this->weekListToHTML(0, 53, $year_days);
            $weeks_html = $this->weekNoToHTML(0, 53, $year_days);
            $u_seconds = $this->viewArrayToHTML($seconds_array);

            $template = <<<HEREDOC
<tr>
    <td>$days_no</td>
    <td>$leap_html</td>
    <td>$years_html</td>
    <td>$months</td>
    <td>$days</td>
    <td>$weeks_html</td>
    <td>$week_html</td>
    <td>$u_seconds</td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td></td>
    <td>$day_total</td>
    <td></td>
</tr>
HEREDOC;
            $html_tr .= $template;
        }
        return $html_tr;
    }

    function viewArrayToHTML($arr, $sep = HTML_EOL, $from = null)
    {
        $arr_first_key = key($arr);
        if (!isset($arr[$arr_first_key])) {
            # print_r(debug_backtrace());
            print_r(get_defined_vars());exit;
        }

        $first_item_type = gettype($arr[$arr_first_key]);
        if ('array' != $first_item_type) {
            $result = implode($sep, $arr);
            return $result;
        }

        $result = array();
        foreach ($arr as $key => $value) {
            $result[] = self::viewArrayToHTML($value);
        }
        $result = implode($sep, $result);
        # echo $result;exit;
        # print_r($result);exit;
        return $result;
    }

    function viewMonthDays($days = array())
    {
        $months_days = array();
        foreach ($days as $key => $value) {
            $months_array = $this->numberToArray($value + 1, 1);
            $months_days[] = $this->viewArrayToHTML($months_array);
        }
        return $months_days_html = implode(HTML_EOL, $months_days);
    }

    function viewMonthNoList($months = array(), $days = array())
    {
        $kvArr = $this->keyValueToArray($months, $days);
        return $kvHtml = $this->viewArrayToHTML($kvArr);
    }

    function viewYearNoList($keys = array(), $values = array())
    {
        $year_array = array();
        $i = 0;
        foreach ($keys as $key) {
            $year_array[] = $values[$i];
            $i++;
        }
        # return $year_array;
        return $kvHtml = $this->viewArrayToHTML($year_array);
    }

    function keyValueToArray($keys = array(), $values = array())
    {
        $i = 0;
        $array = array();
        foreach ($keys as $key) {

            $val = $values[$i] + 1;
            # print_r([$val, $i, $key]); exit;
            for ($j = 1; $j < $val; $j++) {
                $l = $i + 1;
                $k = "$l $j";
                $array[$k] = $key;
            }
            $i++;
        }
        return $array;
    }

    /* 生成星期几天 */
    function weekOne($first_day = 0, $last_day = 6)
    {
        $result = array();
        for ($i = $first_day; $i < $last_day + 1; $i++) {
            $result[] = $i;
        }
        return $result;
    }

    /* 星期列表 */
    function weekList($week_start = 0, $week_end = 28)
    {
        $result = array();
        for ($i = $week_start; $i < $week_end + 1; $i++) {
            $result[] = $this->weekOne();
        }
        return $result;
    }

    /* 合并周天数组 */
    function weeksArray($week_array = array(), $days = 36)
    {
        $week_arr = array();
        $i = 0;
        foreach ($week_array as $week_no_key => $week_no_value) {
            foreach ($week_no_value as $week_one_list) {
                if ($i >= $days) {
                    goto End;
                }
                $week_key = $week_no_key . ' ' . $i;
                $week_arr[$week_key] = $week_one_list;
                $i++;
            }
        }
        End:
        return $week_arr;
    }

    /* 周天循环列表 */
    function weekListToHTML($week_start = 0, $week_end = 28, $days = 36)
    {
        $weekList = $this->weekList($week_start, $week_end);
        $weekArr = $this->weeksArray($weekList, $days);
        return $weekHTML = $this->viewArrayToHTML($weekArr);
    }

    /* 合并几周数组 */
    function weekNoArray($week_array = array(), $days = 365)
    {
        $week_arr = array();
        $i = 0;
        $j = 1;
        foreach ($week_array as $week_no_key => $week_no_value) {
            foreach ($week_no_value as $week_one_list) {
                if ($i >= $days) {
                    goto End;
                }
                $week_key = $week_no_key . ' ' . $i;
                $week_arr[$week_key] = $j;
                $i++;
            }
            $j++;
        }
        End:
        return $week_arr;
    }

    /* 几周循环列表 */
    function weekNoToHTML($week_start = 0, $week_end = 28, $days = 36)
    {
        $weekList = $this->weekList($week_start, $week_end);
        $weekArr = $this->weekNoArray($weekList, $days);
        return $weekHTML = $this->viewArrayToHTML($weekArr);
    }

    /*  */
    function seconds($sec_start = 0, $sec_times = 10, $sec_base = 86400)
    {
        $result = array();
        $seconds = 0;
        for ($i = $sec_start; $i < $sec_times + 1; $i++) {
            $seconds += $sec_base;
            $result[] = $seconds;
        }
        return $result;
    }

    /* 数字转数组合并 */
    function numberToArrayMerge($array = array())
    {
        $arr = array();
        foreach ($array as $key => $value) {
            list($days, $day_start, $year_no) = $value;
            $arr = array_merge($arr, $this->numberToArray($days, $day_start, $year_no));
        }
        return $arr;
    }
    /*
    闰年 年天数，第一天，固定值
    $ar = array();
    $ar[] = array(5, 1, 1);
    $ar[] = array(5, 1, 2);
    $ar[] = array(5, 1, 3);
    $ar[] = array(6, 1, 4);
    */
}


/*
$days_array = numberToArr(733, 366);

for ($i = 366; $i < 733; $i++) {
    $days_array[] = $i;
}
print_r($days_array);exit;
*/
$calendar = new Calendar($request);
$result = $calendar->getAll();
extract($result);
$html = $calendar->viewRows($years);

/*$days_array = $calendar->numberToArray(733, 366);
print_r($days_array);exit;*/

include "e:/env/www/work/wuding/php-app/app/template/list/calendar/index.html";
